home *** CD-ROM | disk | FTP | other *** search
- Eve is an evolving language for describing autonomous, animated
- characters. At its core, eve is based on tcl, the tool command
- language developed by John Ousterhout at Berkeley. For 3D geometry,
- eve uses the RenderMan(TM) interface, which allows it to describe a
- wide area of different geometry and surfaces.
-
- It is assumed that any reader that is serious about learning and using
- eve has gotten the standard documentation for both tcl and RenderMan.
- For tcl, there is a book called "Tcl and the Tk ToolKit" from
- Addison-Wesley. Also, there are the excellent man pages that I include
- in the standard source distribution of WavesWorld. For RenderMan, the
- book "The RenderMan Companion" by Steve Upstill is an excellent
- introduction. If possible, serious readers are urged to try to obtain
- a copy of the document entitled "The RenderMan Interface, Version 3.1,
- September 1989" available from Pixar.
-
- For the remainder of this document, I'll assume that the reader at
- least has access to the man pages for tcl and a copy of the "RenderMan
- Companion."
-
- Eve usually comes in two flavors. The first is really just as a very
- simple layer on top of RIB (RenderMan's file format). In this form,
- eve is really just being used as an interpreted language (vs. a
- compiled one like C), and is really there to allow the user to build
- compact model descriptions which expand to RIB code. The second is
- the more interesting, and is the one used in the WW3DKit, wherein eve
- code is compiled into a displayable, manipulatable shape hierarchy.
-
- Since the model is being constantly reevaluated each time it is
- displayed (as opposed to going straight to a RIB file as in the first
- way), there is an opportunity to change the values of parts of the
- model. Eve supports a notion of an articulated/animated model; that
- is, one which changes over time. It implements this by adding two new
- commands to tcl: one for articulated commands and one for articulated
- procedures. An articulated command is an expression which has
- components which might change over time, while an articulated
- procedure is a eve proc in which all the components are assumed to be
- articulated over time. Perhaps an example is in order...
-
- Let's say we want to define a ball which can squash and stretch. One
- good trick to do this (short of doing some sort of dynamic simulation)
- is to fake it with a "volume preserving" scale. In eve, to define such
- a "squishy" sphere, we might write the following:
-
- ##
- set color {1.0 0.0 0.0}
- set radius 1.0; set zMin [expr {-1*$radius}]; set zMax $radius
- set thetaMax 360.0
- set squish 2.0
-
- startShape aSphere
- Color $color
- Scale [expr sqrt(1./$squish)] [expr sqrt(1./$squish)] $squish
- Sphere $radius $zMin $zMax $thetaMax
- endShape
- ##
-
- When we evaluate the preceding code, we get a shape object named
- aSphere which has 3 RIBCommand objects in it: RIBColor, RIBScale, and
- RIBSphere. We've set the values inside these objects to reflect the
- values of the various variables at the time we created the objects.
- If we drop this in a WW3DWell, for example, we'll get a nicely squished
- sphere.
-
- But if you think about it, it seems a bit of a lose that we had
- variables describing all sorts of aspects of the shape (its radius,
- color, squishiness, etc.) but that once we'd evaluated and compiled
- the shape, that information (the names of the variables or
- expressions) was gone. What if we changed the value of $squish later?
- It would have no effect on the above model. That may be what we want,
- but we also might want the option of affecting the model later. Given
- that we're on a NeXT, and IB is our friend, the most obvious way to do
- this is to attach some sort of UI object to it, like a slider. But
- how do we set up this dependency (i.e. when the value changes the
- object gets notified) in the first place? Well, if we set up a
- wrapper object *around* the RIBCommand we can do this. Such a wrapper
- object would get handed a tcl expression, which it would evaluate.
- Upon evaluation, this tcl expression should yield a valid RIBCommand.
- The wrapper object would then ask the tcl interp to look at the
- expression, tell it what variables are in it, and then ask the tcl
- interp to trace each of the variables, sending a message to the
- wrapper object each time any of the variables was modified so the
- wrapper object can mark itself as dirty. Then when the wrapper object
- is asked for its bounding box or asked to render itself, it checks to
- see if it's dirty. If it isn't, it just asks its RIBCommand for its
- boudning box or tells it to render itself. If the object *is* dirty,
- it throws away its old RIBCommand and asks the tcl interp to
- reevaluate the original expression its based on, and then uses that
- RIBCommand. I call these wrapper objects "EveCommands", and they can
- be written as "EveCmd", "ACmd", "ArticulatedCmd", "eveCmd", "aCmd", or
- "articulatedCmd". For example:
-
- ##
- set color {1.0 0.0 0.0}
- set radius 1.0; set zMin -$radius; set zMax $radius
- set thetaMax 360.0
- set squish 1.0
-
- startShape aSphere
- EveCmd {Color $color}
- EveCmd {Scale [expr sqrt(1./$squish)] [expr sqrt(1./$squish)] $squish}
- EveCmd {Sphere $radius $zMin $zMax $thetaMax}
- endShape
- ##
-
- Well, all that is fine and good for relatively simple shapes, but what
- about more complicated ones? What happens when you want to use tcl
- procedures (proc) to make your code more readable and reusable?
-
- yyyyyyaaaaaaaaaaabbbbbbbbbbbbbbbbbbaaaaaaaaaaa
- yyyyyyaaaaaaaaaaabbbbbbbbbbbbbbbbbbaaaaaaaaaaa
- yyyyyyaaaaaaaaaaabbbbbbbbbbbbbbbbbbaaaaaaaaaaa
- yyyyyyaaaaaaaaaaabbbbbbbbbbbbbbbbbbaaaaaaaaaaa
- yyyyyyaaaaaaaaaaabbbbbbbbbbbbbbbbbbaaaaaaaaaaa
- ##
- set color {1.0 0.0 0.0}
- set radius 1.0; set zMin -$radius; set zMax $radius
- set thetaMax 360.0
- set squish 1.0
-
- proc drawSphere {s r t} {
-
- Scale [expr sqrt(1./$s)] [expr sqrt(1./$s)] $s
- Sphere $r [expr {-1*$r}] $r $t
- }
-
- startShape aSphere
- EveCmd {Color $color}
- EveProc {drawSphere $squish $radius $thetaMax}
- endShape
- ##
-